#include <iostream>
#include <queue>
using namespace std;

/**
 * @brief read and black
 * 有一个长方形的房间,铺着方形瓷砖,瓷砖为红色或黑色。
 * 一个人站在黑色瓷砖上,他可以按上、下、左、右方向移动到相邻的瓷砖。
 * 但他不能在红色瓷砖上移动,只能在黑色瓷砖上移动。编程计算他可以到达的黑色瓷砖的数量。
 * 输入：第1行包含两个正整数W和H,W和H分别表示x方向和y方向上的瓷砖数量。
 * W和H均不超过 20。下面有H行,每行包含W个字符。
 * 每个字符表示一片瓷砖的颜色。用符号表示如下:“*”表示黑色瓷砖;“#”表示红色瓷砖;“@”代表黑色瓷砖上的人,
 * 在数据集中只出现一次。
 * 输出：一个数字,这个人从初始瓷砖能到达的瓷砖总数量(包括起点）。
 */

/*
5 4
****#
*****
#@*** 
*#**#
*/
int w, h;
vector<vector<char>> grid;
bool check(int x, int y){
    return x >= 0 && x < h && y >= 0 && y < w;
}
struct point{
    int x,y;
    point(){

    }
    point(int a, int b){
        x = a;
        y = b;
    }
};
int cnt = 0;
int dirs[4][2] = {
    {-1, 0}, {1, 0}, {0, -1}, {0, 1}
};
void bfs(int x, int y){
    queue<point> q;
    q.push(point(x, y));
    point start, next;
    while(!q.empty()){
        start = q.front();
        q.pop();
        for(int i = 0; i < 4; i++){
            next.x = start.x + dirs[i][0];
            next.y = start.y + dirs[i][1];
            if(check(next.x, next.y) && grid[next.x][next.y] == '*'){
                grid[next.x][next.y] = '#'; //标记访问过
                q.push(next);
                cnt++;
            }
        }
    }
}

int main(){
    cin>>w>>h;
    int x, y;
    for(int i = 0; i < h; i++){
        vector<char> v;
        for(int j = 0; j < w; j++){
            char c;
            cin>>c;
            if(c == '@'){
                x = i;
                y = j;
            }
            v.push_back(c);
        }
        grid.push_back(v);
    }

    //深度优先搜索
    cnt = 0;
    bfs(x, y);
    cout<<cnt<<endl;
    return 0;
}